package org.vaadinpa.gui;

import java.util.List;

import org.vaadinpa.exceptions.TickOccuredException;
import org.vaadinpa.gui.util.NotificationUtil;
import org.vaadinpa.logic.Command;
import org.vaadinpa.logic.CommandHandler;

import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.Reindeer;

@SuppressWarnings("serial")
public abstract class ViewWithCommands extends AbstractView {

	/**
	 * Uses this layout for view specific code
	 */
	private VerticalLayout mainLayout;

	private HorizontalLayout header;

	protected List<? extends Command> activeCommands;

	public ViewWithCommands() {

		// Construct a layout with header and footer

		header = new HorizontalLayout();
		header.setSizeUndefined();
		header.setHeight("75px");
		header.addStyleName(Reindeer.LAYOUT_BLACK);

		Panel headerPanel = new Panel();
		headerPanel.setContent(header);
		headerPanel.setHeight("82px");
		headerPanel.setWidth("100%");
		headerPanel.setScrollable(true);

		mainLayout = new VerticalLayout();
		mainLayout.setSizeUndefined();
		mainLayout.setWidth("100%");
		mainLayout.setMargin(true, false, true, false);
		mainLayout.addStyleName(Reindeer.LAYOUT_BLACK);

		Panel mainPanel = new Panel(mainLayout);
		mainPanel.setStyleName(Reindeer.PANEL_LIGHT);
		mainPanel.setSizeFull();

		super.addComponent(headerPanel);
		super.addComponent(mainPanel);
		setExpandRatio(mainPanel, 1);

		setSpacing(true);
		setSizeFull();
	}

	public void updateCommands() {

		activeCommands = getCommands();
		header.removeAllComponents();

		if (activeCommands.isEmpty()) {
			Label l = new Label("No queued commands");
			l.setSizeUndefined();

			HorizontalLayout hl = new HorizontalLayout();
			hl.addComponent(l);
			hl.setMargin(true);
			header.addComponent(hl);
		} else {
			for (Command c : activeCommands) {

				GridLayout gl = new GridLayout(2, 2);

				Label name = new Label(c.getName());
				gl.addComponent(name, 0, 0);

				Label desc = new Label(c.getDescription());
				gl.addComponent(desc, 0, 1, 1, 1);

				Button cancel = new Button("X");
				cancel.setData(c);
				cancel.setWidth("40px");
				cancel.setImmediate(true);
				cancel.addListener(new ClickListener() {

					public void buttonClick(ClickEvent event) {

						Command command = (Command) event.getButton().getData();
						if (!command.canBeCanceled()) {
							return;
						}
						try {
							CommandHandler.cancel(command);
							NotificationUtil.notify("Command canceled", "");
						} catch (TickOccuredException e) {
							NotificationUtil.warn("A tick has occured",
									"Unfortunately you were too late, the command has already been processed");
						}
						reload();
					}
				});
				gl.addComponent(cancel, 1, 0);

				gl.setWidth("150px");
				// gl.setHeight("100%");
				gl.setColumnExpandRatio(0, 1);
				gl.setStyleName("command");

				header.addComponent(gl);
			}
		}
	}

	protected abstract List<? extends Command> getCommands();

	/*
	 * BEGIN OVERLOADED METHODS
	 */

	@Override
	public void removeAllComponents() {
		mainLayout.removeAllComponents();
	}

	@Override
	public void addComponent(Component c) {
		mainLayout.addComponent(c);
	}

	@Override
	public void addComponent(Component c, int index) {
		mainLayout.addComponent(c, index);
	}

	@Override
	public void setSpacing(boolean enabled) {
		mainLayout.setSpacing(enabled);
	}

	@Override
	public void reload() {
		updateCommands();
	}
}
